
/*
http://xubenyang.me/416
NSLog还是是一件非常expensive的事情，主要体现在这两点：
1.NSLog在打印信息的同时要发送日志，效率低
2.程序一些调试信息通过NSLog发送到System Log之后，很容易被其他人查看到，对你程序的安全性造成了直接的威胁。除了通过xcode的oganizer可以查看console，在iPhone上有一个叫ConsoleLog的程序可以查看你的这些日志
 */


//调试时打开日志
#ifdef DEBUG    //DEBUG
//日志复杂度宏，值为：1-5
#define DLogInfoSimpleLeave 1


NSArray *allSubviews(UIView *aView);
NSArray *allApplicationViews();
NSArray *pathToView(UIView *aView);

//获取本地时间字符串
NSString *getDateString(NSDate *date);

//一个自定义的itoa。最好只处理正数
//负数时，只是简单的在最前边添加符号（这种情况对于二进制而言时不对的）
//算法：一直把取余得到的值组成字符串，最后翻转
//radix: 是基数的意思,即先将n转化为radix进制的数，范围介于2-36，比如10表示10进制。
//int，一般为32和64位。所以str定义为128位，绝对够了
char* myitoa(int n, char* str, int radix);

//打印日志需要的函数
void print0(id formatstring,...);
void print1(const char* function, int line, id formatstring,...);
void print2(const char* filename, const char* function, int line, id formatstring,...);
void print3(const char* filename, const char* function, int line, id formatstring,...);
void print4(const char* filename, const char* function, int line, id formatstring,...);

//0-4，使用printf实现；5，NSLog实现
//0,最简单
//1,函数(行数) 日志内容
//2,文件名 函数(行数) 日志内容
//3,时间 文件名 函数(行数) 日志内容
//4,日期 时间 文件名 函数(行数) 日志内容
//5,日期 时间 程序信息 文件名 函数(行数) 日志内容
#ifndef DLogInfoSimpleLeave
    #define DLogInfoSimpleLeave 1
#endif

#if (DLogInfoSimpleLeave == 0)
    #define DLog(fmt, ...) print0(fmt, ##__VA_ARGS__)
    //打印日志的另一种写法。该方法使用NSString的fomat方法直接格式化字符串
    //要注意的时fomat的写法
    //#define DLog(fmt, ...) printf("%s\n", [[NSString stringWithFormat:(@"" fmt), ##__VA_ARGS__] UTF8String]);
#elif (DLogInfoSimpleLeave == 1)
    #define DLog(fmt, ...) print1(__PRETTY_FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
#elif (DLogInfoSimpleLeave == 2)
    #define DLog(fmt, ...) print2(__FILE__, __PRETTY_FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
#elif (DLogInfoSimpleLeave == 3)
    #define DLog(fmt, ...) print3(__FILE__, __PRETTY_FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
#elif (DLogInfoSimpleLeave == 4)
    #define DLog(fmt, ...) print4(__FILE__, __PRETTY_FUNCTION__, __LINE__, fmt, ##__VA_ARGS__)
#else
    #define DLog(fmt, ...) do {\
    NSString* file = [[NSString alloc] initWithFormat:@"%s", __FILE__]; \
    NSLog((@"%@ %s(%d) " fmt), [file lastPathComponent], __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); \
    [file release]; \
    } while(0)
#endif

//fun(line) agrs...
#define DLogFun() DLog(@"")
#define DLogFunS() DLog(@"==>start")
#define DLogFunE() DLog(@"==>end")
#define DLogCount(str, p) DLog(@"%@,retainCount = %d", str, [p retainCount])
#define DLogCF CFShow 

//打印view树日志
#define DLogView(view) \
    NSLog(@"the view's subviews:"); \
    CFShow(allSubviews(view))

#define DLogAllView() \
    NSLog(@"application window subviews:"); \
    CFShow(allApplicationViews())	

#define DLogParentView(subview) \
    NSLog(@"path of the view:"); \
    CFShow(pathToView(subview))

#define DLogStr(str) DLog(@"%@", str)
#define DLogRange(str, range) DLog(@"%@%@", str, NSStringFromRange(range))
#define DLogPoint(str, point) DLog(@"%@%@", str, NSStringFromCGPoint(point))
#define DLogSize(str, size) DLog(@"%@%@", str, NSStringFromCGSize(size))
#define DLogRect(str, rect) DLog(@"%@%@", str, NSStringFromCGRect(rect))
#define DLogDate(str, date) DLog(@"%@%@", str, getDateString(date))
#define DLogException(str, e) DLog(@"%@ %@:%@", str, [e name], [e reason])
#define DLogNSTimeInterval(str, t) DLog(@"%@:%.0f秒", str, t)

#define DLogIntHex(str, num) DLog(@"%@:0x%x", str, num)
#define DLogInt(str, num) DLog(@"%@:%d", str, num)
#define DLogIntOctal(str, num) DLog(@"%@:O%o", str, num)
//负数的二进制有问题 
#define DLogIntBinary(str, num) do {\
char rst[129] = {0};\
myitoa(num, rst, 2);\
DLog(@"%@:%s",str, rst);\
} while(0)


#else   //DEBUG


#define DLog(...)
#define DLogFun()
#define DLogFunS()
#define DLogFunE()
#define DLogCount(p)

#define DLogCF
#define DLogView(view)
#define DLogAllView()
#define DLogParentView(subview)

#define DLogStr(str)
#define DLogRange(str, range)
#define DLogPoint(str, point)
#define DLogSize(str, size)
#define DLogRect(str, rect)
#define DLogDate(str, date)
#define DLogException(str, e)
#define DLogNSTimeInterval(str, t)

#define DLogIntHex(str, num)
#define DLogInt(str, num)
#define DLogIntOctal(str, num)
#define DLogIntBinary(str, num)

#endif  //DEBUG





/*
//真机日志文件
//==========================================================
- (void)redirectNSLogToDocumentFolder{
// 把stderr重定向到该app的Document/curdata.log文件中
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *fileName =[NSString stringWithFormat:@"%@.log",[NSDate date]];
NSString *logFilePath = [documentsDirectory stringByAppendingPathComponent:fileName];
freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
}
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// 真机测试时保存日志
if ([CDeviceInfo getModelType] != SIMULATOR) {
[self redirectNSLogToDocumentFolder];
}
}


//模拟器日志文件
//==========================================================
- (void)redirectNSLogToDocumentFolder{
//模拟器测试时，可以把stderr重定向到任何文件（已经测试），如~/wwp.log
NSString *logFilePath = @"~/wwp.log";
freopen([logFilePath cStringUsingEncoding:NSASCIIStringEncoding],"a+",stderr);
}

- (void)applicationDidFinishLaunching:(UIApplication *)application {
[self redirectNSLogToDocumentFolder];
}

*/
